﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	EventManager.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.ComponentModel;

namespace Smart.Common
{
	/// <summary>
	/// Event manager
	/// </summary>
	[Localizable(false)]
	public class EventManager : IEventManager
	{
		public SPServicesInstance Services { get; set; }

		public EventManager(SPServicesInstance services)
		{
			Services = services;
		}

		public static readonly string AnyWeb = "-=Any=-";

		public NamedEventHandlerInfoMap Map = new NamedEventHandlerInfoMap();

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb or "/"</param>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1>(string webName, string eventName, int priority, NamedEventHandler<TArg1> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(webName, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb or "/"</param>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1, TArg2>(string webName, string eventName, int priority, NamedEventHandler<TArg1, TArg2> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(webName, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb or "/"</param>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1, TArg2, TArg3>(string webName, string eventName, int priority, NamedEventHandler<TArg1, TArg2, TArg3> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(webName, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb or "/"</param>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1, TArg2, TArg3, TArg4>(string webName, string eventName, int priority, NamedEventHandler<TArg1, TArg2, TArg3, TArg4> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(webName, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1>(string eventName, int priority, NamedEventHandler<TArg1> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(AnyWeb, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1, TArg2>(string eventName, int priority, NamedEventHandler<TArg1, TArg2> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(AnyWeb, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1, TArg2, TArg3>(string eventName, int priority, NamedEventHandler<TArg1, TArg2, TArg3> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(AnyWeb, eventName, handler, priority);
		}

		/// <summary>
		/// Register event handler for named event
		/// </summary>
		/// <param name="eventName">Event name</param>
		/// <param name="priority"> 0 - highest priority</param>
		/// <param name="handler">Event handler</param>
		public void Register<TArg1, TArg2, TArg3, TArg4>(string eventName, int priority, NamedEventHandler<TArg1, TArg2, TArg3, TArg4> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (eventName.IsNullOrEmpty() || handler == null || priority < 0)
				throw new ArgumentException();

			Map.Register(AnyWeb, eventName, handler, priority);
		}

		/// <summary>
		/// Unregister event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb</param>
		/// <param name="eventName">Event name</param>
		/// <param name="handler">Event handler</param>
		public void Unregister<TArg1>(string webName, string eventName, NamedEventHandler<TArg1> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			Map.Unregister(webName, eventName, handler);
		}

		/// <summary>
		/// Unregister event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb</param>
		/// <param name="eventName">Event name</param>
		/// <param name="handler">Event handler</param>
		public void Unregister<TArg1, TArg2>(string webName, string eventName, NamedEventHandler<TArg1, TArg2> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			Map.Unregister(webName, eventName, handler);
		}

		/// <summary>
		/// Unregister event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb</param>
		/// <param name="eventName">Event name</param>
		/// <param name="handler">Event handler</param>
		public void Unregister<TArg1, TArg2, TArg3>(string webName, string eventName, NamedEventHandler<TArg1, TArg2, TArg3> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			Map.Unregister(webName, eventName, handler);
		}

		/// <summary>
		/// Unregister event handler for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb</param>
		/// <param name="eventName">Event name</param>
		/// <param name="handler">Event handler</param>
		public void Unregister<TArg1, TArg2, TArg3, TArg4>(string webName, string eventName, NamedEventHandler<TArg1, TArg2, TArg3, TArg4> handler)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			Map.Unregister(webName, eventName, handler);
		}

		/// <summary>
		/// Unregister all event handlers for named event
		/// </summary>
		/// <param name="webName">Web.Name or EventManager.AnyWeb</param>
		/// <param name="eventName">Event name</param>
		public void Unregister(string webName, string eventName)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			if (webName.IsNullOrEmpty())
				webName = "/";

			Map.Unregister(webName, eventName);
		}

		/// <summary>
		/// Unregister all event handlers for named event
		/// </summary>
		/// <param name="eventName">Event name</param>
		public void Unregister(string eventName)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			Map.Unregister(AnyWeb, eventName);
		}

		/// <summary>
		/// Fire event in current Web
		/// </summary>
		public void FireEvent<TArg1>(string eventName, TArg1 arg1)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			var webName = SPH.GetWeb().Name;

			if (webName.IsNullOrEmpty())
				webName = "/";

			FireEvent(webName, eventName, arg1);
		}

		/// <summary>
		/// Fire event in current Web
		/// </summary>
		public void FireEvent<TArg1, TArg2>(string eventName, TArg1 arg1, TArg2 arg2)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			var webName = SPH.GetWeb().Name;

			if (webName.IsNullOrEmpty())
				webName = "/";

			FireEvent(webName, eventName, arg1, arg2);
		}

		/// <summary>
		/// Fire event in current Web
		/// </summary>
		public void FireEvent<TArg1, TArg2, TArg3>(string eventName, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			var webName = SPH.GetWeb().Name;

			if (webName.IsNullOrEmpty())
				webName = "/";

			FireEvent(webName, eventName, arg1, arg2, arg3);
		}

		/// <summary>
		/// Fire event in current Web
		/// </summary>
		public void FireEvent<TArg1, TArg2, TArg3, TArg4>(string eventName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			if (Services.SiteId != SPH.GetSite().ID)
				throw new InvalidOperationException("EventManager is used with different Site!");

			var webName = SPH.GetWeb().Name;

			if (webName.IsNullOrEmpty())
				webName = "/";

			FireEvent(webName, eventName, arg1, arg2, arg3, arg4);
		}

		/// <summary>
		/// Fire event in supplied Web
		/// </summary>
		public void FireEvent<TArg1>(string webName, string eventName, TArg1 arg1)
		{
			if (webName.IsNullOrEmpty())
				webName = "/";

			if (Map.FireEvent(AnyWeb, eventName, arg1))
			{
				Map.FireEvent(webName, eventName, arg1);
			}
		}

		/// <summary>
		/// Fire event in supplied Web
		/// </summary>
		public void FireEvent<TArg1, TArg2>(string webName, string eventName, TArg1 arg1, TArg2 arg2)
		{
			if (webName.IsNullOrEmpty())
				webName = "/";

			if (Map.FireEvent(AnyWeb, eventName, arg1, arg2))
			{
				Map.FireEvent(webName, eventName, arg1, arg2);
			}
		}

		/// <summary>
		/// Fire event in supplied Web
		/// </summary>
		public void FireEvent<TArg1, TArg2, TArg3>(string webName, string eventName, TArg1 arg1, TArg2 arg2, TArg3 arg3)
		{
			if (webName.IsNullOrEmpty())
				webName = "/";

			if (Map.FireEvent(AnyWeb, eventName, arg1, arg2, arg3))
			{
				Map.FireEvent(webName, eventName, arg1, arg2, arg3);
			}
		}

		/// <summary>
		/// Fire event in supplied Web
		/// </summary>
		public void FireEvent<TArg1, TArg2, TArg3, TArg4>(string webName, string eventName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
		{
			if (webName.IsNullOrEmpty())
				webName = "/";

			if (Map.FireEvent(AnyWeb, eventName, arg1, arg2, arg3, arg4))
			{
				Map.FireEvent(webName, eventName, arg1, arg2, arg3, arg4);
			}
		}
	}
}